<template>
  <div class="flex flex-col h-full overflow-hidden">
    <app-header/>

    <main>
      <h2 class="page-title">{{ editMode ? '编辑报警地址组' : '新增报警地址组' }}</h2>

      <form @submit.prevent="saveAlarmGroup" id="alarm-group-edit-add-form" class="config-form">
        <input type="hidden" v-if="editMode" id="alarm-group-id" v-model="alarmGroupData.id">

        <div class="form-section">
          <h3 class="form-section-title">地址组基本信息</h3>
          <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-2">
            <div class="form-group">
              <label for="alarm-group-address" class="form-label">地址 <span class="text-red-500">*</span></label>
              <input type="text" id="alarm-group-address" v-model="alarmGroupData.address" class="form-input"
                     placeholder="例如: MW8000" :readonly="editMode" required>
              <p class="form-description" v-if="editMode">地址通常不能修改。</p>
            </div>
            <div class="form-group">
              <label for="alarm-group-category" class="form-label">类别</label>
              <input type="text" id="alarm-group-category" v-model="alarmGroupData.category" class="form-input"
                     placeholder="例如: 轴报警 (可选)">
            </div>
          </div>
        </div>

        <div class="form-section">
          <h3 class="form-section-title">位 (Bit) 配置 (0-15)</h3>
          <p class="form-description mb-4">填写每个位的报警描述，未填写的位将被忽略。</p>
          <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-2">
            <div class="form-group" v-for="i in 16" :key="`bit-config-${i-1}`">
              <label :for="`bit-desc-${i-1}`" class="form-label">Bit {{ i - 1 }} 描述</label>
              <input type="text" :id="`bit-desc-${i-1}`" v-model="bitDescriptions[i-1]" class="form-input"
                     :placeholder="`Bit ${i-1} 报警描述 (可选)`">
            </div>
          </div>
        </div>


        <div class="button-group">
          <button type="button" id="btn-cancel-edit" class="hmi-button hmi-button-secondary" @click="goBack">
            <i class="fas fa-times"></i>取消
          </button>
          <button type="submit" id="btn-save-alarm-group" class="hmi-button hmi-button-primary" :disabled="isSaving">
            <i :class="isSaving ? 'fas fa-spinner fa-spin' : 'fas fa-save'"></i>{{
              isSaving ? '保存中...' : (editMode ? '保存修改' : '新增地址组')
            }}
          </button>
        </div>
      </form>
    </main>

    <div v-if="notification.show" id="notification" class="notification"
         :class="{ 'notification-success': notification.type === 'success', 'notification-error': notification.type === 'error', 'show': notification.show }">
      <span id="notification-message">{{ notification.message }}</span>
    </div>
  </div>
</template>

<script setup>
import {ref, reactive, onMounted, onUnmounted, watch, computed} from 'vue' // 导入 onUnmounted
import {useRouter, useRoute, onBeforeRouteLeave} from 'vue-router' // 导入 useRouter, useRoute, onBeforeRouteLeave
// 不再需要导入 AppHeader，因为它已全局配置

const router = useRouter() // 获取路由实例
const route = useRoute() // 获取当前路由信息

// --- 响应式数据 ---
// 报警地址组数据对象
const alarmGroupData = reactive({
  id: null, // Will be populated if in edit mode
  address: '',
  category: '',
  bits: {} // Object to store bit configurations (key is bit index 0-15)
})

// 使用数组来绑定 16 个位的输入框
const bitDescriptions = ref(Array(16).fill(''))
// 如果需要 Code 字段，也需要一个类似的数组
// const bitCodes = ref(Array(16).fill(''));

// 用于跟踪表单是否有未保存的更改
const hasUnsavedChanges = ref(false)
const isSaving = ref(false) // 用于控制保存按钮的加载状态

// 通知状态
const notification = reactive({
  show: false,
  message: '',
  type: 'success', // 'success' or 'error'
  timeoutId: null // 用于存储定时器ID
})

// 判断是编辑模式还是新增模式
const editMode = computed(() => route.params.id !== undefined) // 根据路由参数中是否有 ID 来判断

// 记录加载时的原始配置，用于判断是否有更改
let initialAlarmGroupData = {}
let initialBitDescriptions = []


// --- 方法 ---

// 显示通知
const showNotification = (message, type = 'success') => {
  notification.show = true
  notification.message = message
  notification.type = type
  if (notification.timeoutId) {
    clearTimeout(notification.timeoutId)
  }
  notification.timeoutId = setTimeout(() => {
    notification.show = false
  }, 3000)
}

// 加载报警地址组数据 (仅在编辑模式下调用)
const loadAlarmGroupData = async (groupId) => {
  console.log('Loading alarm group data for ID:', groupId)
  try {
    let group = null;
    if (window.electronAPI && window.electronAPI.alarmGroups) {
      group = await window.electronAPI.alarmGroups.getById(groupId);
      if (!group) {
        throw new Error('报警地址组不存在');
      }
    } else {
      console.warn('未检测到Electron API，使用模拟数据');
      // 模拟加载数据 (开发环境)
      await new Promise(resolve => setTimeout(resolve, 500));
      const sampleAlarmGroupConfigData = [
        {
          id: 'group_mw8000', address: 'MW8000', category: '轴报警',
          bits: {
            0: {code: 'M710', description: '主轴左右[X1]轴伺服故障，请检查！'},
            1: {code: 'M711', description: '主轴前后[Y1]轴伺服故障，请检查！'},
            // ... other bits
          }
        },
        {
          id: 'group_mw8003', address: 'MW8003', category: '轴限位报警',
          bits: {
            0: {code: 'M710P', description: '主轴左右[X1]轴正限位异常，请检查！'},
            1: {code: 'M710N', description: '主轴左右[X1]轴负限位异常，请检查！'}
          }
        }
      ];
      group = sampleAlarmGroupConfigData.find(g => g.id === groupId);
      if (!group) {
        throw new Error('模拟环境：报警地址组不存在');
      }
    }

    // 填充表单数据
    Object.assign(alarmGroupData, {
      id: group.id,
      address: group.address,
      category: group.category || '',
      bits: group.bits || {}
    });

    // 填充bit描述输入框
    bitDescriptions.value = Array(16).fill(''); // 重置数组
    if (group.bits) {
      for (const bitIndex in group.bits) {
        const index = parseInt(bitIndex, 10);
        // 检查描述是否存在后再赋值
        if (index >= 0 && index < 16 && group.bits[bitIndex].description !== undefined) {
          bitDescriptions.value[index] = group.bits[bitIndex].description;
        }
      }
    }

    // 记录初始状态用于判断是否有修改
    initialAlarmGroupData = JSON.parse(JSON.stringify(alarmGroupData));
    initialBitDescriptions = [...bitDescriptions.value]; // 复制数组
    
  } catch (error) {
    console.error('加载报警地址组数据失败:', error);
    showNotification(`加载失败: ${error.message}`, 'error');
    // 加载失败时导航回列表页
    setTimeout(() => {
      router.replace('/settings/alarm-config');
    }, 2000);
  }
};


// 保存报警地址组 (新增或编辑)
const saveAlarmGroup = async () => {
  const form = document.getElementById('alarm-group-edit-add-form');
  // 使用 Vue 的 $refs 或获取DOM元素进行验证
  if (!form || !form.checkValidity()) {
    showNotification('请填写所有必填项 (*)', 'error');
    // 触发表单的原生验证提示
    if (form) form.reportValidity();
    return;
  }

  // 额外客户端验证：检查地址是否填写
  if (!alarmGroupData.address) { // Already covered by required
    showNotification('地址不能为空', 'error');
    return;
  }
  
  // 地址格式验证：通常应符合 MW 或 D 开头加数字的格式
  const addressRegex = /^(MW|D)\d+$/i;
  if (!addressRegex.test(alarmGroupData.address)) {
    showNotification('地址格式不正确，应为MW或D开头加数字', 'error');
    return;
  }

  isSaving.value = true; // 显示保存中状态

  // 构建要保存的数据对象
  const dataToSave = {
    id: alarmGroupData.id, // 在编辑模式下保留ID
    address: alarmGroupData.address.toUpperCase(), // 转为大写确保一致性
    category: alarmGroupData.category || '', // 确保空字符串而非undefined
    bits: {} // 初始化空的bits对象
  };

  // 收集非空的位配置
  bitDescriptions.value.forEach((desc, index) => {
    if (desc.trim() !== '') { // 只包含非空描述
      dataToSave.bits[index] = {
        description: desc.trim(),
        code: `BIT${index}` // 生成默认的code
      };
    }
  });

  console.log(`保存报警地址组数据 (模式: ${editMode.value ? '编辑' : '新增'}):`, dataToSave);

  try {
    let result = { success: false, error: '未知错误' };
    
    if (window.electronAPI && window.electronAPI.alarmGroups) {
      if (editMode.value) {
        // 编辑现有报警地址组
        result = await window.electronAPI.alarmGroups.update(alarmGroupData.id, dataToSave);
      } else {
        // 新增报警地址组
        result = await window.electronAPI.alarmGroups.add(dataToSave);
      }
    } else {
      console.warn('未检测到Electron API，模拟保存操作');
      // 模拟保存成功 (开发环境)
      await new Promise(resolve => setTimeout(resolve, 1000));
      result = { success: true };
    }

    if (result.success) {
      showNotification(`报警地址组 ${editMode.value ? '更新' : '新增'}成功!`, 'success');
      hasUnsavedChanges.value = false; // 重置更改状态
      // 保存成功后导航回列表页
      setTimeout(() => {
        router.push('/settings/alarm-config');
      }, 500);
    } else {
      throw new Error(result.error || '操作失败');
    }
  } catch (error) {
    console.error(`${editMode.value ? '更新' : '新增'}报警地址组失败:`, error);
    showNotification(`${editMode.value ? '更新' : '新增'}失败: ${error.message}`, 'error');
  } finally {
    isSaving.value = false; // 隐藏保存中状态
  }
};

// 导航回报警地址组列表页面，检查未保存更改
const goBack = () => {
  router.back() // 假设报警地址组列表页路由是 /settings/alarm-config
}


// --- Watchers ---
// 监听 alarmGroupData 和 bitDescriptions 的变化来设置 hasUnsavedChanges
watch([alarmGroupData, bitDescriptions], ([newAlarmGroupData, newBitDescriptions]) => {
  // 排除 isSaving 状态变化导致的 watch 触发
  if (isSaving.value) return

  // 比较当前状态与初始加载时的状态
  let currentData = {
    address: newAlarmGroupData.address,
    category: newAlarmGroupData.category,
    bits: {}
  }
  newBitDescriptions.forEach((desc, index) => {
    if (desc.trim() !== '') {
      currentData.bits[index] = {description: desc.trim()}
      // if needed: code: bitCodes.value[index] ? bitCodes.value[index].trim() : ''
    }
  })

  hasUnsavedChanges.value = JSON.stringify(currentData) !== JSON.stringify(initialAlarmGroupData)
  console.log('Form changed, hasUnsavedChanges:', hasUnsavedChanges.value)

}, {deep: true}) // 深度监听 alarmGroupData 对象和 bitDescriptions 数组


// --- Vue Router 导航守卫 ---
// 在路由离开前检查是否有未保存更改
onBeforeRouteLeave((to, from, next) => {
  // 检查目标路由是否是删除确认页面，如果是则允许离开
  if (to.path.startsWith('/settings/alarm-config/delete/')) {
    next()
    return
  }
  next() // 没有更改，允许离开
})


// --- 生命周期钩子 ---
onMounted(() => {
  console.log('Alarm Group Edit/Add Page mounted')
  // 根据路由参数判断是新增还是编辑模式
  if (editMode.value) {
    const groupId = route.params.id
    if (groupId) {
      loadAlarmGroupData(groupId) // 编辑模式下加载报警地址组数据
    } else {
      console.error('Edit mode requires an alarm group ID in the route.')
      showNotification('加载报警地址组数据失败，缺少地址组 ID', 'error')
      // 如果缺少 ID，可以导航回列表页
      // router.replace('/settings/alarm-config');
    }
  } else {
    // 新增模式下初始化空数据
    Object.assign(alarmGroupData, {id: null, address: '', category: '', bits: {}})
    bitDescriptions.value = Array(16).fill('')
    // if needed: bitCodes.value = Array(16).fill('');
    initialAlarmGroupData = JSON.parse(JSON.stringify(alarmGroupData)) // Record initial state
    initialBitDescriptions = [...bitDescriptions.value]
    // if needed: initialBitCodes = [...bitCodes.value];
  }
})

// 导入了 onUnmounted，即使此处模拟代码没有显式使用，也符合您的要求
onUnmounted(() => {
  console.log('Alarm Group Edit/Add Page unmounted')
  // 清理通知定时器
  if (notification.timeoutId) {
    clearTimeout(notification.timeoutId)
  }
})

// ESC键返回功能
onMounted(() => {
  const handleEscape = (event) => {
    if (event.key === 'Escape') {
      // 触发与取消按钮相同的逻辑，包括未保存检查
      goBack()
    }
  }
  document.addEventListener('keydown', handleEscape)
  onUnmounted(() => {
    document.removeEventListener('keydown', handleEscape)
  })
})


</script>

<style scoped>
/* --- 将原始 HTML 文件中的所有自定义样式复制到这里 --- */

/* --- Inherited Styles & Color Palette --- */
/* 根变量通常在全局 CSS 中定义，但为了完整性，这里列出 */
/* :root {
  --bg-primary: #f3f4f6;
  --bg-secondary: #ffffff;
  --text-primary: #1f2937;
  --text-secondary: #6b7280;
  --text-tertiary: #9ca3af;
  --border-color: #e5e7eb;
  --accent-blue: #3b82f6;
  --status-green: #22c55e;
  --status-yellow: #eab308;
  --status-red: #ef4444;
  --status-gray: #6b7280;
  --status-off: #9ca3af;
  --online-green: #10b981;
  --offline-red: #f43f5e;
} */

/* body 样式通常由父组件或全局 App.vue 控制 */
/* body {
  font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
} */


/* --- Header (Consistent) --- */
/* Header 样式已移至 AppHeader.vue 或全局 */


/* --- Main Content Area --- */
main {
  flex-grow: 1;
  padding: 1.5rem;
  overflow-y: auto; /* Enable scrolling for form */
}

/* --- Configuration Form (Common Styles) --- */
.config-form {
  background-color: var(--bg-secondary);
  border-radius: 0.75rem;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
  padding: 1.5rem;
  border: 1px solid var(--border-color);
  max-width: 1000px; /* Adjusted max width for bit fields */
  margin: 0 auto; /* Center form */
}

.form-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 1.5rem;
  text-align: center;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 0.75rem;
}

.form-section {
  margin-bottom: 1.5rem;
}

.form-section-title {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.75rem;
  border-left: 3px solid var(--accent-blue);
  padding-left: 0.5rem;
}

.form-group {
  margin-bottom: 1rem;
}

.form-label {
  display: block;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 0.25rem;
}

.form-input, .form-select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  font-size: 0.875rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  background-color: #f9fafb;
}

.form-input:focus, .form-select:focus {
  outline: none;
  border-color: var(--accent-blue);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
  background-color: white;
}

.form-input:required:invalid, .form-select:required:invalid {
  border-color: var(--status-red);
}

.form-input[readonly] {
  background-color: #e5e7eb;
  cursor: not-allowed;
  opacity: 0.7;
  color: var(--text-secondary);
}

.form-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3csvg%3e");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: 2.5rem;
}

.form-description {
  font-size: 0.7rem;
  color: var(--text-tertiary);
  margin-top: 0.25rem;
}

/* Input group for select + button (if any) */
.input-button-group {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.input-button-group .form-select {
  flex-grow: 1;
}

.input-button-group .hmi-button {
  flex-shrink: 0;
}


/* Toggle Switch (Common Styles) */
.toggle-switch {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.toggle-label {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 20px;
  flex-shrink: 0;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
  border-radius: 20px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 14px;
  width: 14px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

/* Apply background color based on checked state in Vue with binding */
.slider.checked {
  background-color: var(--accent-blue);
}

/* Apply transform based on checked state in Vue with binding */
input:checked + .slider:before {
  transform: translateX(20px);
}


/* --- Buttons (Common Styles) --- */
.button-group {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  margin-top: 2rem;
  border-top: 1px solid var(--border-color);
  padding-top: 1.5rem;
}

.hmi-button {
  padding: 0.6rem 1.2rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border: 1px solid transparent;
  transition: all 0.2s ease;
  cursor: pointer;
}

/* Adjusted padding for small button */
.hmi-button-small {
  padding: 0.35rem 0.7rem;
  font-size: 0.75rem;
}

.hmi-button i {
  font-size: 1em;
}

/* HMI Button Colors - Defined by variables */
.hmi-button-primary {
  background-color: var(--accent-blue);
  color: white;
  border-color: var(--accent-blue);
}

.hmi-button-primary:hover {
  background-color: #2563eb;
  border-color: #2563eb;
}

/* Specific hover color */
.hmi-button-secondary {
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  border-color: var(--border-color);
}

.hmi-button-secondary:hover {
  background-color: #f9fafb;
  border-color: #d1d5db;
}

/* Specific hover color */
.hmi-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* --- Notification (Common Styles) --- */
.notification {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.75rem 1.25rem;
  border-radius: 0.5rem;
  color: white;
  font-size: 0.875rem;
  font-weight: 500;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
  z-index: 100;
}

.notification.show {
  opacity: 1;
  visibility: visible;
}

/* Notification Colors - Defined by variables */
.notification-success {
  background-color: var(--status-green);
}

.notification-error {
  background-color: var(--status-red);
}


/* Body styles from original inline style */
/* max-width: 800px; max-height: 600px; margin: auto; */
/* These should ideally be managed in a layout component or App.vue */

</style>
